unit Main;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  Winapi.OpenGL,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,

  GLS.SceneViewer,
  GLS.Texture,
  GLS.Scene,
  GLS.GeomObjects,
  GLS.Objects,
  GLS.Coordinates,
  
  GLS.BaseClasses,
  GLS.RenderContextInfo;

type

  //Derived dummycube. Used only to save rci.
  TMyDummyCube = class(TGLDummyCube)
  protected
   public
    procedure DoRender(var rci : TGLRenderContextInfo; RenderSelf, RenderChildren : Boolean); override;
  end;

  TfMain = class(TForm)
    GLScene: TGLScene;
    GLSceneViewer: TGLSceneViewer;
    GLCamera: TGLCamera;
    GLDummyCube: TGLDummyCube;
    GLLightSource1: TGLLightSource;
    SphereOuter: TGLSphere;
    GLTeapot: TGLTeapot;
    SphereInner: TGLSphere;
    GLLightSource2: TGLLightSource;
    GLCylinder1: TGLCylinder;
    Sphere: TGLSphere;
    procedure GLSceneViewerPostRender(Sender: TObject);
    procedure GLSceneViewerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure GLSceneViewerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure GLSceneViewerBeforeRender(Sender: TObject);
  private
    MouseX : Integer;
    MouseY : Integer;
  public
  end;

const
  Plane0: array [0..3] of Double = (0, 0, -1, 0.0);
  Plane1: array [0..3] of Double = (-1, 0, 0, 0.0);

var
  fMain    : TfMain;
  SavedRci : TGLRenderContextInfo;

implementation

{$R *.dfm}

//________________________________________________________________________________________________________________________________
procedure TfMain.FormCreate(Sender: TObject);
var
  Cube : TMyDummyCube;
begin
  Cube := TMyDummyCube.Create(Self);
  GLScene.Objects.AddChild(Cube);
end;

//________________________________________________________________________________________________________________________________
procedure TfMain.GLSceneViewerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  MouseX := X;
  MouseY := Y;
end;

//________________________________________________________________________________________________________________________________
procedure TfMain.GLSceneViewerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if ssLeft in Shift then begin
    GLCamera.MoveAroundTarget(MouseY - Y, MouseX - X);
    MouseX := X;
    MouseY := Y;
  end;
end;

//________________________________________________________________________________________________________________________________
procedure TfMain.GLSceneViewerBeforeRender(Sender: TObject);
begin
  //Enable first clipping plane before ordinary render
  glEnable(GL_Clip_Plane0);
  glClipPlane(GL_Clip_Plane0, @Plane0);
end;

//________________________________________________________________________________________________________________________________
procedure TfMain.GLSceneViewerPostRender(Sender: TObject);
begin
  //Disable the first plane
  glDisable(GL_Clip_Plane0);

  //Enable second plane
  glEnable(GL_Clip_Plane1);
  glClipPlane(GL_Clip_Plane1, @Plane1);

  //Redraw the whole scene once more using the saved rci
  GLScene.Objects.Render(SavedRci);

  //Disable the second plane
  glDisable(GL_Clip_Plane1);
end;

//********************************************************************************************************************************
{ TMyCube }
//********************************************************************************************************************************
procedure TMyDummyCube.DoRender(var rci: TGLRenderContextInfo; RenderSelf, RenderChildren: Boolean);
begin
  //Save the rci for use in the GLSceneViewerPostRender event
  //Could this be done in a better way?
  SavedRci := rci;
end;

end.
